<!DOCTYPE html>
<html>

<head>
  <title>WMS GetFeatureInfo (Image Layer)</title>
  <!-- <script src="https://cdn.jsdelivr.net/npm/ol@v8.1.0/dist/ol.js"></script>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v8.1.0/ol.css"> -->
  <!-- <link rel="stylesheet" href="https://openlayers.org/en/v3.20.1/css/ol.css" type="text/css">
  <script
    src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
  <script src="https://openlayers.org/en/v3.20.1/build/ol.js"></script> -->

  <!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v8.1.0/ol.css">
  <script src="https://cdn.jsdelivr.net/npm/ol@v8.1.0/dist/ol.js"></script> -->

  <link rel="stylesheet" href="./assets/v6.15.1-dist/ol.css">
  <script src="./assets/v6.15.1-dist/ol.js"></script>

  <style>
    html,
    body {
      width: 100%;
      height: 100%;
    }

    .map {
      width: 100%;
      height: 100%;
      color: #1791fc;
    }
  </style>
</head>

<body>
  <div id="map" class="map"></div>
  <div id="info">&nbsp;</div>
  <script>
    var authInfo = {
      account: "hubei",  //填入账户 aHViZWk=
      // passwd: "2023hubei@shengtai",  //填入密码
      // account: "aHViZWk=",  //填入账户
      passwd: "MjAyM2h1YmVpQHNoZW5ndGFp"  //填入密码

    };

    function getWMSLayer() {
      // var url = "http://210.12.142.176:7090/onemap22/rest/wms?LAYERS=WGS84&FORMAT=image%2Fjpeg&VERSION=1.1.1&STYLES=&TRANSPARENT=FALSE&SERVICE=WMS&REQUEST=GetMap&SRS=EPSG%3A4326&BBOX=90,22.5,112.5,45&WIDTH=256&HEIGHT=256&ACCOUNT=hubei&PASSWD=MjAyM2h1YmVpQHNoZW5ndGFp";
      // http://210.12.142.176:7090/onemap22/rest/wms?LAYERS=WGS84&FORMAT=image%2Fjpeg&VERSION=1.1.1&STYLES=&TRANSPARENT=FALSE&SERVICE=WMS&REQUEST=GetMap&SRS=EPSG%3A4326&BBOX=90,22.5,112.5,45&WIDTH=256&HEIGHT=256&ACCOUNT=hubei&PASSWD=MjAyM2h1YmVpQHNoZW5ndGFp&
      var wmsSource = new ol.source.ImageWMS({
        // url: url,
        url: 'http://210.12.142.176:7090/onemap22/rest/wms',
        params: {
          'LAYERS': 'WGS84',
          "FORMAT": "image/jpeg",		// 请求的瓦片格式
          "VERSION": "1.1.1",     // 请求使用的WMS版本
          "STYLES": "",		// 请求的图层样式
          // "TRANSPARENT": "FALSE",
          "WIDTH": 256,
          "HEIGHT": 256,
          "ACCOUNT": "hubei",
          "PASSWD": "MjAyM2h1YmVpQHNoZW5ndGFp",
          "BBOX": "90,22.5,112.5,45",
        },
        projection: "EPSG:4326",
        serverType: 'geoserver',
        // crossOrigin: 'anonymous'
      });

      return wmsSource;

    }

    function getWMSTileLayer() {
      var wmsSource = new ol.source.TileWMS({
        // url: url,
        url: 'http://210.12.142.176:7090/onemap22/rest/wms',
        params: {
          'LAYERS': 'WGS84',
          "FORMAT": "image/jpeg",		// 请求的瓦片格式
          "VERSION": "1.1.1",     // 请求使用的WMS版本
          "STYLES": "",		// 请求的图层样式
          // "TRANSPARENT": "FALSE",
          "WIDTH": 256,
          "HEIGHT": 256,
          "ACCOUNT": "hubei",
          "PASSWD": "MjAyM2h1YmVpQHNoZW5ndGFp",
          "BBOX": "90,22.5,112.5,45",
        },
        projection: "EPSG:4326",
        serverType: 'geoserver',
        // crossOrigin: 'anonymous'
      });

      return wmsSource;

    }


    var wmsSource = getWMSLayer();

    var wmsLayer = new ol.layer.Image({
      source: wmsSource
    });

    var wmsTileSource = getWMSTileLayer();
    var wmsTileLayer = new ol.layer.Tile({
      source: wmsTileSource,
    })


    // 加载点位
    var rome = new ol.Feature({
      geometry: new ol.geom.Point(ol.proj.fromLonLat([112, 30]))
    });

    rome.setStyle(new ol.style.Style({
      image: new ol.style.Icon(/** @type {olx.style.IconOptions} */({
        color: '#8959A8',
        // src: 'https://openlayers.org/en/v3.20.1/examples/data/dot.png'
        src: "./assets/imgs/plant_sampled.png"
      }))
    }));

    function createStyle(src, img) {
      return new ol.style.Style({
        image: new ol.style.Icon(/** @type {olx.style.IconOptions} */({
          anchor: [0.5, 1],
          src: src,
          // img: img,
          scale: 0.2,
          // imgSize: img ? [img.width, img.height] : [20, 20],

        }))
      });
    }

    var iconFeature = new ol.Feature(new ol.geom.Point([112, 30]));
    // iconFeature.set('style', createStyle('https://openlayers.org/en/v3.20.1/examples/data/icon.png', undefined));
    iconFeature.set('style', createStyle('./assets/imgs/plant_sampled.png', undefined));
    // iconFeature.setStyle(createStyle('https://openlayers.org/en/v3.20.1/examples/data/icon.png', undefined));


    var vectorSource = new ol.source.Vector({
      features: [rome]
    });

    var vectorLayer = new ol.layer.Vector({
      source: vectorSource
    });

    // 示例数据，包含点位的坐标和样式信息  
    var features = [[112.686865, 30.928462], [120, 34], [117, 32], [115, 27],
    ['114.08253191741544', '29.769630115867855']
    ];

    var array = [];

    // 遍历点位数组，将每个点位添加到地图上  
    features.forEach((feature, index) => {
      var iconFeature = new ol.Feature({
        geometry: new ol.geom.Point(feature),
        name: '点位' + index,
      });
      // iconFeature.set('style', createStyle('https://openlayers.org/en/v3.20.1/examples/data/icon.png', undefined));
      iconFeature.set('style', createStyle('./assets/imgs/plant_sampled.png', undefined));
      array.push(iconFeature)
    });

    var map = new ol.Map({
      layers: [
        // wmsLayer,
        wmsTileLayer,
        vectorLayer,
        new ol.layer.Vector({
          style: function (feature) {
            return feature.get('style');
          },
          source: new ol.source.Vector({ features: [iconFeature] })
        }),
      ],
      target: 'map',
      view: new ol.View({
        projection: "EPSG:4326",
        center: [112, 32],
        zoom: 5
      })
    });

    let markers = new ol.layer.Vector({
      style: function (feature) {
        return feature.get('style');
      },
      source: new ol.source.Vector({ features: array })
    })


    map.addLayer(markers); // 将点位添加到地图上的矢量图层中  

    // 在组件的类中添加以下方法，用于处理点击事件  
    // function handleMapClick(event) {
    //   const pixel = this.map.getEventPixel(event.browserEvent); // 获取点击位置的像素坐标  
    //   const feature = this.map.forEachFeatureAtPixel(pixel, { hitTolerance: 5 }); // 检测点击位置上的要素，设置hitTolerance来允许一些偏移量  
    //   if (feature) {
    //     // 点击位置上有要素被点击，执行相关操作，例如弹出一个提示框显示要素的信息或者执行其他自定义逻辑  
    //     console.log('Icon clicked!');
    //   }
    // }

    map.on('click', function (evt) {
      const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
        return feature;
      });
      if (feature) {
        // 点击位置上有要素被点击，执行相关操作，例如弹出一个提示框显示要素的信息或者执行其他自定义逻辑  
        console.log('Icon clicked!', feature);

        //   popup.setPosition(evt.coordinate);
        //   $(element).popover({
        //     placement: 'top',
        //     html: true,
        //     content: feature.get('name'),
        //   });
        //   $(element).popover('show');
        // } else {
        //   $(element).popover('dispose');
        // }
      }
    });
    // setTimeout(() => {
    //   map.removeLayer(markers);
    //   console.log('3秒后移除markers');
    // }, 3000)

    var circleStyle = new ol.style.Style({
      fill: new ol.style.Fill({ color: 'rgba(255, 0, 0, 0.1)' }), // 填充颜色  
      stroke: new ol.style.Stroke({ color: 'red', width: 2 }), // 边框颜色和宽度  

    })

    // 在 EPSG：3857 坐标系下创建圆形对象
    var circle3857 = new ol.geom.Circle(
      ol.proj.transform([112, 30], 'EPSG:4326', 'EPSG:3857'),
      10000, // 半径（单位为米）
      'XY'
    )

    // 将圆形对象转化为 4326
    var circle4326 = circle3857.transform('EPSG:3857', 'EPSG:4326');

    // 创建包含样式的 Feature 对象, 圆心坐标为 EPSG:3857 下的坐标  
    var feature1 = new ol.Feature({
      geometry: circle4326
    });
    feature1.setStyle(circleStyle);

    // // 将 Feature 对象添加到矢量图层中  
    var vectorLayer11 = new ol.layer.Vector({
      source: new ol.source.Vector({ features: [feature1] }),
      zIndex: 4
    });
    map.addLayer(vectorLayer11);

    console.log(vectorLayer11, 'v1');

    // 矢量图层
    var layer = initVectorLayer();

    /**
     * @todo 矢量图层
     * @returns {VectorLayer}
     * @constructor
     */
    function initVectorLayer() {
      //实例化一个矢量图层Vector作为绘制层
      let source = new ol.source.Vector();
      //创建一个图层
      let customVectorLayer = new ol.layer.Vector({
        source: source,
        zIndex: 2,
        //设置样式
        style: new ol.style.Style({
          //边框样式
          stroke: new ol.style.Stroke({
            color: 'red',
            width: 5,
            lineDash: [3, 5]
          }),
          //填充样式
          fill: new ol.style.Fill({
            color: 'rgba(0, 0, 255, 0.3)',
          }),
          image: new ol.style.Circle({
            radius: 9,
            fill: new ol.style.Fill({
              color: 'red',
            })
          })
        }),
      });
      //将绘制层添加到地图容器中
      map.addLayer(customVectorLayer);

      return customVectorLayer;
    }



    function transformProjection(arr, EPSG, EPSG2) {
      try {
        if (EPSG2 && EPSG) {
          if (arr && arr.length === 4) {
            return ol.proj.transformExtent(arr, EPSG, EPSG2);
          } else {
            return ol.proj.transform(arr, EPSG, EPSG2);
          }
        }
        return undefined;
      } catch (e) {
        console.error(e);
      }
    }

    function getStyle(stroke = '#ff0000', fill = [0, 0, 255, 0.3]) {

      return new ol.style.Style({
        //边框样式
        stroke: new ol.style.Stroke({
          color: stroke,
          width: 2,
        }),
        //填充样式
        fill: new ol.style.Fill({
          color: fill,
        })
      })
    }

    function clearLayer() {
      layer && layer.getSource().clear();
    }

    // 半径
    const radius = 10010;
    const center = [112, 31.2];

    // 通过获取地图经纬度和米的转换关系，来计算经纬度半径
    function createCircle1(radiusTemp) {

      clearLayer();

      radiusTemp = radiusTemp || radius;

      // 通过投影获取每个经纬度单位为多少米，也就是一度多少米
      const metersPerUnit = map.getView().getProjection().getMetersPerUnit();

      // 创建圆形对象
      const circleFeature = new ol.Feature({
        geometry: new ol.geom.Circle(center, radiusTemp / metersPerUnit, 'XY'),
      });

      circleFeature.setStyle(getStyle());

      layer.getSource().addFeature(circleFeature);

      // 定位
      positionLayer(layer);
    }

    // 通过投影转换的方式，将米半径转为经纬度半径
    function createCircle2(radiusTemp) {

      clearLayer();

      radiusTemp = radiusTemp || radius;

      const circle = new ol.geom.Circle(center,
        transformProjection([radiusTemp, 0], 'EPSG:3857', 'EPSG:4326')[0]
        -
        transformProjection([0, 0], 'EPSG:3857', 'EPSG:4326')[0], 'XY');

      const circleFeature = new ol.Feature({
        geometry: circle,
      });

      circleFeature.setStyle(getStyle('#00ff00', [255, 0, 255, 0.3]));

      layer.getSource().addFeature(circleFeature);

      // 定位
      positionLayer(layer);
    }

    // 先创建米的圆，在转为经纬的圆
    function createCircle3(radiusTemp) {

      clearLayer();

      radiusTemp = radiusTemp || radius;

      // 创建 3857 投影下的圆形对象
      const circleIn3857 = new ol.geom.Circle(
        ol.proj.transform(center, 'EPSG:4326', 'EPSG:3857'), radiusTemp, 'XY');

      // 将圆形对象转为 4326
      const circle = circleIn3857.transform('EPSG:3857', 'EPSG:4326');

      const circleFeature = new ol.Feature({
        geometry: circle,
      });

      circleFeature.setStyle(getStyle('#0000ff', [255, 0, 0, 0.3]));

      layer.getSource().addFeature(circleFeature);

      // 定位
      positionLayer(layer);
    }

    // 定位到图层 layer
    function positionLayer() {

      const extent = layer.getSource().getExtent();
      //定位范围
      map.getView().fit(extent, {
        duration: 100,//动画的持续时间,
        callback: function () {
          // alert("positionLayer compete !")
        },
      });
    }

    var boundaryList = [
      ['114.08253191741544', '29.769630115867855'],
      ['114.08265088391994', '29.769697701739396'],
      ['114.08278655683151', '29.769503128592497'],
      ['114.08265684062167', '29.76943277743491'],
      ['114.08253191741544', '29.769630115867855']
    ]

    var boundaryList2 = boundaryList.map(item => {
      return ol.proj.transform(item, 'EPSG:4326', 'EPSG:3857')
    });

    console.log(boundaryList2, '转换后的boudaryList2');
    let polygon3857 = new ol.geom.Polygon([
      boundaryList2
    ]);

    let polygon4326 = polygon3857.transform('EPSG:3857', 'EPSG:4326');
    let polygonFeature = new ol.Feature({
      geometry: polygon4326
    });
    let polygonStyle = new ol.style.Style({
      fill: new ol.style.Fill({ color: 'rgba(255, 255, 255, 0)' }), // 填充颜色  
      stroke: new ol.style.Stroke({ color: '#47D4DE', width: 2 }), // 边框颜色和宽度  
    })
    polygonFeature.setStyle(polygonStyle);


    layer.getSource().addFeature(polygonFeature);
    // positionLayer(layer);



    // createCircle1();
    // createCircle2();
    // createCircle3();

    
    // 天地图 wmts 配置
    var projection = ol.proj.get("EPSG:4326"); //设置坐标系
    var projectionExtent = projection.getExtent();
    //分辨率

    //   下面这个maxtrixIdx 一定要和 resolutions 的数量length对应，这个多少个，分辨率resolution就要多少个，
    //    然后，这个的里面0,1,2,3 对应 wmts服务能力文档的 <ows:Identifier> 参数，一般是数字，或者’变量+_5‘,数字等，
    //     resolution 则是可以多个图层公用一个分辨率
    var matrixIds = [
      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    ];
    var resolutions = [
      1.40625, 0.703125, 0.3515625, 0.17578125, 0.087890625, 0.0439453125,
      0.02197265625, 0.010986328125, 0.0054931640625, 0.00274658203125,
      0.001373291015625, 0.0006866455078125, 0.00034332275390625,
      0.000171661376953125, 0.0000858306884765625, 0.00004291534423828125,
      0.000021457672119140625, 0.000010728836059570312, 0.000005364418029785156,
      0.000002682209014892578, 0.000001341104507446289,
    ];


    var tRoadWMTS = new ol.layer.Tile({
      title: '天地图路网',
      source: new ol.source.WMTS({
        name: '路网',
        // url: 'http://t4.tianditu.gov.cn/cia_c/wmts?tk=9df1e2d38f43b8983357c36603d366e5&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=c&TILEMATRIX=4&TILEROW=2&TILECOL=12&FORMAT=tiles',
        url: 'http://t4.tianditu.gov.cn/cia_c/wmts?tk=9df1e2d38f43b8983357c36603d366e5&TILEMATRIXSET=c',
        layer: "cia",
        format: 'tiles',
        style: 'default',
        projection: projection,
        tileGrid: new ol.tilegrid.WMTS({
          origin: ol.extent.getTopLeft(projectionExtent),
          resolutions: resolutions,
          matrixIds: matrixIds,
        }),
        wrapX: true,
      })
    })

    map.addLayer(tRoadWMTS);




  </script>
</body>

</html>